//! 抽象语法树定义
//! 
//! 定义了脚本语言的AST节点类型，包括：
//! - 语句类型
//! - 表达式类型
//! - 值类型
//! - 程序结构

use std::collections::HashMap;
use serde::{Deserialize, Serialize};

/// 程序（语句列表）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Program {
    pub statements: Vec<Statement>,
}

/// 语句类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Statement {
    /// 变量声明: var name = value;
    VarDecl {
        name: String,
        value: Expression,
    },
    
    /// 变量赋值: name = value;
    Assignment {
        name: String,
        value: Expression,
    },
    
    /// 表达式语句: expression;
    Expression(Expression),
    
    /// SQL查询: sql `SELECT * FROM table` [with params];
    SqlQuery {
        query: String,
        parameters: Vec<Expression>,
    },
    
    /// 函数调用: function_name(args);
    FunctionCall {
        name: String,
        args: Vec<Expression>,
    },
    
    /// 条件语句: if (condition) { then_block } [else { else_block }]
    If {
        condition: Expression,
        then_block: Vec<Statement>,
        else_block: Option<Vec<Statement>>,
    },
    
    /// 循环语句: for (var in iterable) { body }
    For {
        var: String,
        iterable: Expression,
        body: Vec<Statement>,
    },
    
    /// while循环: while (condition) { body }
    While {
        condition: Expression,
        body: Vec<Statement>,
    },
    
    /// 返回语句: return [value];
    Return {
        value: Option<Expression>,
    },
    
    /// 中断语句: break;
    Break,
    
    /// 继续语句: continue;
    Continue,
    
    /// 块语句: { statements }
    Block(Vec<Statement>),
}

/// 表达式类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Expression {
    /// 字面量值
    Literal(Value),
    
    /// 变量引用
    Variable(String),
    
    /// 二元操作: left op right
    BinaryOp {
        left: Box<Expression>,
        operator: BinaryOperator,
        right: Box<Expression>,
    },
    
    /// 一元操作: op operand
    UnaryOp {
        operator: UnaryOperator,
        operand: Box<Expression>,
    },
    
    /// 函数调用: function_name(args)
    FunctionCall {
        name: String,
        args: Vec<Expression>,
    },
    
    /// 数组访问: array[index]
    ArrayAccess {
        array: Box<Expression>,
        index: Box<Expression>,
    },
    
    /// 对象访问: object.field
    ObjectAccess {
        object: Box<Expression>,
        field: String,
    },
    
    /// 数组字面量: [elements]
    Array(Vec<Expression>),
    
    /// 对象字面量: {key: value, ...}
    Object(HashMap<String, Expression>),
    
    /// 条件表达式: condition ? true_expr : false_expr
    Conditional {
        condition: Box<Expression>,
        true_expr: Box<Expression>,
        false_expr: Box<Expression>,
    },
    
    /// SQL子查询: (SELECT ...)
    SqlSubquery(String),
}

/// 二元操作符
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BinaryOperator {
    // 算术操作符
    Add,        // +
    Subtract,   // -
    Multiply,   // *
    Divide,     // /
    Modulo,     // %
    Power,      // **
    
    // 比较操作符
    Equal,      // ==
    NotEqual,   // !=
    Less,       // <
    LessEqual,  // <=
    Greater,    // >
    GreaterEqual, // >=
    
    // 逻辑操作符
    And,        // &&
    Or,         // ||
    
    // 字符串操作符
    Concat,     // ++
    
    // 集合操作符
    In,         // in
    NotIn,      // not in
}

/// 一元操作符
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UnaryOperator {
    Plus,       // +
    Minus,      // -
    Not,        // !
    BitwiseNot, // ~
}

/// 值类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Value {
    /// 空值
    Null,
    
    /// 布尔值
    Boolean(bool),
    
    /// 整数
    Integer(i64),
    
    /// 浮点数
    Float(f64),
    
    /// 字符串
    String(String),
    
    /// 数组
    Array(Vec<Value>),
    
    /// 对象
    Object(HashMap<String, Value>),
    
    /// 日期时间
    DateTime(chrono::DateTime<chrono::Utc>),
    
    /// 二进制数据
    Binary(Vec<u8>),
}

impl Program {
    /// 创建新程序
    pub fn new(statements: Vec<Statement>) -> Self {
        Self { statements }
    }
    
    /// 创建空程序
    pub fn empty() -> Self {
        Self {
            statements: Vec::new(),
        }
    }
    
    /// 添加语句
    pub fn add_statement(&mut self, statement: Statement) {
        self.statements.push(statement);
    }
    
    /// 获取语句数量
    pub fn statement_count(&self) -> usize {
        self.statements.len()
    }
}

impl Value {
    /// 获取值的类型名称
    pub fn type_name(&self) -> &'static str {
        match self {
            Value::Null => "null",
            Value::Boolean(_) => "boolean",
            Value::Integer(_) => "integer",
            Value::Float(_) => "float",
            Value::String(_) => "string",
            Value::Array(_) => "array",
            Value::Object(_) => "object",
            Value::DateTime(_) => "datetime",
            Value::Binary(_) => "binary",
        }
    }
    
    /// 检查是否为真值
    pub fn is_truthy(&self) -> bool {
        match self {
            Value::Null => false,
            Value::Boolean(b) => *b,
            Value::Integer(i) => *i != 0,
            Value::Float(f) => *f != 0.0,
            Value::String(s) => !s.is_empty(),
            Value::Array(a) => !a.is_empty(),
            Value::Object(o) => !o.is_empty(),
            Value::DateTime(_) => true,
            Value::Binary(b) => !b.is_empty(),
        }
    }
    
    /// 转换为字符串
    pub fn to_string(&self) -> String {
        match self {
            Value::Null => "null".to_string(),
            Value::Boolean(b) => b.to_string(),
            Value::Integer(i) => i.to_string(),
            Value::Float(f) => f.to_string(),
            Value::String(s) => s.clone(),
            Value::Array(a) => {
                let elements: Vec<String> = a.iter().map(|v| v.to_string()).collect();
                format!("[{}]", elements.join(", "))
            },
            Value::Object(o) => {
                let pairs: Vec<String> = o.iter()
                    .map(|(k, v)| format!("{}: {}", k, v.to_string()))
                    .collect();
                format!("{{{}}}", pairs.join(", "))
            },
            Value::DateTime(dt) => dt.to_rfc3339(),
            Value::Binary(b) => format!("binary({} bytes)", b.len()),
        }
    }
    
    /// 转换为JSON值
    pub fn to_json(&self) -> serde_json::Value {
        match self {
            Value::Null => serde_json::Value::Null,
            Value::Boolean(b) => serde_json::Value::Bool(*b),
            Value::Integer(i) => serde_json::Value::Number((*i).into()),
            Value::Float(f) => {
                serde_json::Number::from_f64(*f)
                    .map(serde_json::Value::Number)
                    .unwrap_or(serde_json::Value::Null)
            },
            Value::String(s) => serde_json::Value::String(s.clone()),
            Value::Array(a) => {
                let elements: Vec<serde_json::Value> = a.iter().map(|v| v.to_json()).collect();
                serde_json::Value::Array(elements)
            },
            Value::Object(o) => {
                let mut map = serde_json::Map::new();
                for (k, v) in o {
                    map.insert(k.clone(), v.to_json());
                }
                serde_json::Value::Object(map)
            },
            Value::DateTime(dt) => serde_json::Value::String(dt.to_rfc3339()),
            Value::Binary(b) => {
                // 将二进制数据编码为base64
                serde_json::Value::String(base64::encode(b))
            },
        }
    }
    
    /// 从JSON值创建
    pub fn from_json(json: serde_json::Value) -> Self {
        match json {
            serde_json::Value::Null => Value::Null,
            serde_json::Value::Bool(b) => Value::Boolean(b),
            serde_json::Value::Number(n) => {
                if let Some(i) = n.as_i64() {
                    Value::Integer(i)
                } else if let Some(f) = n.as_f64() {
                    Value::Float(f)
                } else {
                    Value::Null
                }
            },
            serde_json::Value::String(s) => Value::String(s),
            serde_json::Value::Array(a) => {
                let elements: Vec<Value> = a.into_iter().map(Value::from_json).collect();
                Value::Array(elements)
            },
            serde_json::Value::Object(o) => {
                let mut map = HashMap::new();
                for (k, v) in o {
                    map.insert(k, Value::from_json(v));
                }
                Value::Object(map)
            },
        }
    }
}

impl std::fmt::Display for Value {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.to_string())
    }
}

impl From<bool> for Value {
    fn from(b: bool) -> Self {
        Value::Boolean(b)
    }
}

impl From<i64> for Value {
    fn from(i: i64) -> Self {
        Value::Integer(i)
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Self {
        Value::Float(f)
    }
}

impl From<String> for Value {
    fn from(s: String) -> Self {
        Value::String(s)
    }
}

impl From<&str> for Value {
    fn from(s: &str) -> Self {
        Value::String(s.to_string())
    }
}

impl From<Vec<Value>> for Value {
    fn from(a: Vec<Value>) -> Self {
        Value::Array(a)
    }
}

impl From<HashMap<String, Value>> for Value {
    fn from(o: HashMap<String, Value>) -> Self {
        Value::Object(o)
    }
}

// 为了避免循环依赖，这里先添加一个简单的base64编码函数
mod base64 {
    pub fn encode(input: &[u8]) -> String {
        // 简单的base64编码实现
        const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        let mut result = String::new();
        
        for chunk in input.chunks(3) {
            let mut buf = [0u8; 3];
            for (i, &byte) in chunk.iter().enumerate() {
                buf[i] = byte;
            }
            
            let b = ((buf[0] as u32) << 16) | ((buf[1] as u32) << 8) | (buf[2] as u32);
            
            result.push(CHARS[((b >> 18) & 63) as usize] as char);
            result.push(CHARS[((b >> 12) & 63) as usize] as char);
            result.push(if chunk.len() > 1 { CHARS[((b >> 6) & 63) as usize] as char } else { '=' });
            result.push(if chunk.len() > 2 { CHARS[(b & 63) as usize] as char } else { '=' });
        }
        
        result
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_value_creation() {
        let null_val = Value::Null;
        assert_eq!(null_val.type_name(), "null");
        assert!(!null_val.is_truthy());
        
        let bool_val = Value::Boolean(true);
        assert_eq!(bool_val.type_name(), "boolean");
        assert!(bool_val.is_truthy());
        
        let int_val = Value::Integer(42);
        assert_eq!(int_val.type_name(), "integer");
        assert!(int_val.is_truthy());
        
        let str_val = Value::String("hello".to_string());
        assert_eq!(str_val.type_name(), "string");
        assert!(str_val.is_truthy());
    }
    
    #[test]
    fn test_value_conversion() {
        let val = Value::Integer(42);
        assert_eq!(val.to_string(), "42");
        
        let json = val.to_json();
        assert_eq!(json, serde_json::Value::Number(42.into()));
        
        let back = Value::from_json(json);
        assert!(matches!(back, Value::Integer(42)));
    }
    
    #[test]
    fn test_program_creation() {
        let mut program = Program::empty();
        assert_eq!(program.statement_count(), 0);
        
        program.add_statement(Statement::VarDecl {
            name: "x".to_string(),
            value: Expression::Literal(Value::Integer(42)),
        });
        
        assert_eq!(program.statement_count(), 1);
    }
}
